package ru.vsu.amm.fuzzy;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * Класс для вычисления LOWA-оператора
 * 
 * @author Иванов Илья
 * @since 06 января 2013
 */
public class LOWA {
	
	public static Scale calc(List<Scale> scores, double[] weights) {
		if (scores.size() < 1 || scores.size() != weights.length)
			throw new RuntimeException("Некорректные данные");
		
		Collections.sort(scores);
		Collections.reverse(scores);
		
		return combination(scores, Arrays.copyOf(weights, weights.length), 0);
	}
	
	public static Scale calc(List<Scale> scores, Quantifier quantifire) {
		if (scores.size() < 1)
			throw new RuntimeException("Некорректный вектор оценок");
		
		Collections.sort(scores);
		Collections.reverse(scores);
		
		double[] weights = quantifire.getWeightVector(scores.size());
		
		return combination(scores, weights, 0);
	}
	
	private static Scale combination(List<Scale> scores, double[] weights, int k) {
		if (k == scores.size() - 1)
			return scores.get(k);
		else {			
			double sum = 0;
			int next = k + 1;
			for (int i = next; i < weights.length; i++)
				sum += weights[i];
			if (Double.compare(sum, 0.0) == 0)
				return scores.get(k);
			
			for (int i = next; i < weights.length; i++)
				weights[i] /= sum;
			
			int j = scores.get(k).ordinal();
			int i = combination(scores, weights, next).ordinal();
			
			return Scale.getByIndex(Math.min(Scale.T, i + (int) Math.round(weights[k] * (j - i))));
		}
	}
}